#include "./include/2440addr.h"
#include "./include/sys_dbg.h"
#include "./include/interrupt.h"

//TODO:
//	FIQ和IRQ统一进行处理
//  增加优先级设置功能
//  考虑吧中断优先级仲裁的机制加载进来
typedef void (*isrFunc)(void);

typedef struct IntVectorTable{
	UINT32 *pRamIrqBase;
	UINT32 irqCapacity;
	UINT32 *pRamFiqBase;
	UINT32 fiqCapacity;
}IntVectorTable;

extern UINT32 Image$$VECTOR$$ZI$$Base;
extern UINT32 Image$$VECTOR$$ZI$$Limit;

IntVectorTable g_IntVectorTable;

void ClearPending(UINT32 bit){
	register UINT32 i;
	rSRCPND = bit;
	rINTPND = bit;
	i = rINTPND;
}

void ClearSubPending(UINT32 bit)
{
	register UINT32 i;
	rSUBSRCPND = bit;
	i = rINTPND;
}

void interrupt_regIRQIsr(UINT32 intNum, UINT32 isrFunc){
	SYS_ASSERT(intNum < MAX_INTERRUPT_COUNT);
	g_IntVectorTable.pRamIrqBase[intNum] = isrFunc;
}

void interrupt_regFIQIsr(UINT32 intNum, UINT32 isrFunc){
	SYS_ASSERT(intNum < MAX_INTERRUPT_COUNT);
	g_IntVectorTable.pRamFiqBase[intNum] = isrFunc;
}

void interrupt_initISR(void){
	UINT32 *pVectorBase = &Image$$VECTOR$$ZI$$Base;
	UINT32 *pVectorLimit = &Image$$VECTOR$$ZI$$Limit;
	UINT32 *p = pVectorBase;

	SYS_ASSERT((p+2*INT_MAX_COUNT)<=pVectorLimit);
	
	while(p<pVectorLimit){
		*p++ = 0;
	}

	g_IntVectorTable.pRamIrqBase = pVectorBase;
	g_IntVectorTable.irqCapacity = INT_MAX_COUNT;
	g_IntVectorTable.pRamFiqBase = pVectorBase + INT_MAX_COUNT;
	g_IntVectorTable.fiqCapacity = INT_MAX_COUNT;
}

void interrupt_executeIrqISR(UINT32 intNum){
	SYS_ASSERT(intNum < MAX_INTERRUPT_COUNT);
	isrFunc pFunc= (isrFunc)(g_IntVectorTable.pRamIrqBase[intNum]);
	pFunc();
}

void interrupt_executeFiqISR(UINT32 intNum){
	SYS_ASSERT(intNum < MAX_INTERRUPT_COUNT);
	isrFunc pFunc= (isrFunc)(g_IntVectorTable.pRamFiqBase[intNum]);
	pFunc();
}